{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name '你好' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-a04a6f21729b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m你好\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name '你好' is not defined"
     ]
    }
   ],
   "source": [
    "print(你好) # 此时抛出了一个 NameError 异常"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好\n"
     ]
    }
   ],
   "source": [
    "print(\"你好\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "try 你好 出错.\n"
     ]
    }
   ],
   "source": [
    "\n",
    "try:\n",
    "    print(你好)\n",
    "except:\n",
    "    print(\"try 你好 出错.\")\n",
    "else:\n",
    "    print(\"如果都没有发生异常\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "刚刚　i 或者　j 类型对应不上，我们转换　一个类型即可处理异常，　处理后：结果是:10a\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "try:\n",
    "    # 运行识别的代码\n",
    "except:\n",
    "    # 如果 try 部分引发了异常， 则执行此处的代码\n",
    "else:\n",
    "    # 如果都没有发生异常\n",
    "'''\n",
    "\n",
    "\n",
    "\n",
    "#　处理多种异常\n",
    "i = 10\n",
    "j = 'a'\n",
    "\n",
    "try:\n",
    "    print(i+j)\n",
    "except NameError: # 这里一定要指明异常的类型\n",
    "    i = j = 2\n",
    "    print(\"刚刚　i 或者　j 没有进行初始化数据，　现在我们将其都初始化为2, 结果是:\")\n",
    "    print(i + j)\n",
    "except TypeError:\n",
    "    print(\"刚刚　i 或者　j 类型对应不上，我们转换　一个类型即可处理异常，　处理后：结果是:\" + str(i) + str(j))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 自定义异常"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 在python 中，要想实现在某种情况下引发某种自定义异常的功能，就可以使用　raise 语句。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8\n",
      "9\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-13-e40deb8a964f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m7\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m9\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m     \u001b[0;32mraise\u001b[0m \u001b[0mNameError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      7\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: "
     ]
    }
   ],
   "source": [
    "i = 8\n",
    "print(i)\n",
    "\n",
    "if i > 7:\n",
    "    print(9)\n",
    "    raise NameError\n",
    "    print(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**自定义一个异常类的实例：**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SoSError: 我错了\n"
     ]
    }
   ],
   "source": [
    "class SoSError(Exception):  # １．必须继承 Exception类，　2. 按照命名规范，以Error结尾\n",
    "    def __init__(self):\n",
    "        Exception.__init__(self)\n",
    "\n",
    "try:\n",
    "    i = 8\n",
    "    if i > 7:\n",
    "        raise SoSError()\n",
    "except SoSError:\n",
    "    print(\"SoSError: 我错了\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## try...finally 的使用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "无论　是否发生异常，　try...finally 语句都将执行　最后的代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "b\n",
      "不管上面　是否异常，　我必须输出　hello world!\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "# try...finally 语句的语法格式为：\n",
    "try:\n",
    "    # 运行识别的代码\n",
    "finally:\n",
    "    # 退出时总会执行的语句\n",
    "'''\n",
    "\n",
    "\n",
    "# 不管上面　是否异常，　我必须输出　hello world!\n",
    "\n",
    "try:\n",
    "    print(b)\n",
    "except NameError:\n",
    "    print(\"b\")\n",
    "finally:\n",
    "    print(\"不管上面　是否异常，　我必须输出　hello world!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
